package com.kly.sc.api.application.service.utils;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.fqgj.base.services.redis.RedisClient;
import com.fqgj.common.api.Response;
import com.fqgj.common.utils.CollectionUtils;
import com.fqgj.common.utils.StringUtils;
import com.jsoniter.JsonIterator;
import com.kly.dto.MemberDto;
import com.kly.dto.ProductDto;
import com.kly.sc.api.application.config.AppConfigs;
import com.kly.sc.api.application.constant.ApiRedisKeys;
import com.kly.sc.api.application.consts.Constants;
import com.kly.sc.api.application.enums.SwitchTypeEnum;
import com.kly.sc.api.application.helper.RequestLocalInfo;
import com.kly.sc.api.application.utils.JwtUtils;
import com.kly.sc.api.infras.app.RequestBasicInfo;
import com.kly.sc.api.infras.exception.ApplicationException;
import com.kly.service.MemberService;
import com.kly.service.ProductService;
import com.kly.user.dto.SwitchManageDto;
import com.kly.user.enums.AppCodeEnum;
import com.kly.user.enums.AppEnum;
import com.kly.user.service.UserSwitchManageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.method.P;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;

@Component
public class BaseComponent extends AppConfigs {

    @Autowired
    RedisClient redisClient;

    @Resource
    ProductService productService;

    @Resource
    MemberService memberService;

    private final static String PRODUCT = "Product";
    /**
     * 开关打开
     */
    private final static Integer switchEnable = 1;

    @Resource
    UserSwitchManageService userSwitchManageService;

    /**
     * 获取userCode值，此处无需校验token，当进入此方法则token已通过验证
     *
     * @return userCode
     */
    public String getCurrentUserCode() {
        String token = RequestLocalInfo.getRequestBasicInfo().getToken();
        return JwtUtils.getAuthentication(token).getName();
    }


    /**
     * 获取产品信息
     **/
    public ProductDto getProductDto(String productCode) {
        Response<ProductDto> listResponse = productService.queryProductsByProductCode(getAppCode(), productCode);
        if (listResponse.isSuccess() && listResponse.getData() != null) {
            return listResponse.getData();
        }
        throw new ApplicationException("The product not exists, productCode=" + productCode);
    }


    /**
     * 从缓存或者服务中获取会员信息。
     *
     * @param userCode 用户编码
     * @return 会员信息，如果不存在则返回null
     */
    public MemberDto retrieveMemberFromCacheOrService(String userCode) {
        // 如果缓存中没有则从服务中获取
        final String appCode = RequestLocalInfo.getRequestBasicInfo().getAppCode();
        Response<MemberDto> memberInfo = memberService.getMemberInfo(userCode, appCode);
        if (memberInfo.isSuccess() && memberInfo.getData() != null) {
            long between = DateUtil.between(new DateTime(), new DateTime(memberInfo.getData().getExpiryDate()), DateUnit.SECOND, false);
            redisClient.set(ApiRedisKeys.USER_MEMBER.getValue(), JSONUtil.toJsonStr(memberInfo.getData()), between, userCode);
        }
        return memberInfo.isSuccess() ? memberInfo.getData() : null;
    }

    protected Boolean showTurnOns() {
        final RequestBasicInfo requestBasicInfo = RequestLocalInfo.getRequestBasicInfo();
        String packageName = requestBasicInfo.getApplicationID();
        String appVersionName = requestBasicInfo.getAppVersionName();
        Integer appVersion = StringUtils.isEmpty(requestBasicInfo.getAppVersion()) ? 99999 : Integer.parseInt(requestBasicInfo.getAppVersion());

        //默认关闭走nacos，开启走后台管理配置
        if(getSwitchManageAdmin(getAppCode())){
            Response<List<SwitchManageDto>>  response = userSwitchManageService.getSwitchManageList(packageName, SwitchTypeEnum.TURN_ONS.getCode(), appVersionName, appVersion);

            if(Objects.nonNull(response) && Objects.nonNull(response.getData()) && response.isSuccess()&& !response.getData().isEmpty()){
                return response.getData().parallelStream().anyMatch(o -> o.getStatus() == 1);
            }
            return Boolean.FALSE;
        }else{
            if (StringUtils.isEmpty(getTurnOnsSwitch(requestBasicInfo.getAppCode()))) {
                return Boolean.FALSE;
            }

            final JSONArray ppAndPvConfigArray = JSONUtil.parseArray(getTurnOnsSwitch(requestBasicInfo.getAppCode()));
            if (CollectionUtils.isEmpty(ppAndPvConfigArray)) {
                return Boolean.FALSE;
            }

            return ppAndPvConfigArray.stream().anyMatch(o -> {
                cn.hutool.json.JSONObject obj = (cn.hutool.json.JSONObject) o;
                if (requestBasicInfo.getAppVersionName().equals(obj.getStr("versionCode"))
                        && requestBasicInfo.getAppVersion().equals(obj.getStr("versionSerialNo"))) {
                    return obj.getInt("enableFlag").equals(switchEnable);
                }
                return Boolean.FALSE;
            });
        }
    }

    /**
     * 开关打开
     */
    protected Boolean showPPPV() {
        final RequestBasicInfo requestBasicInfo = RequestLocalInfo.getRequestBasicInfo();
        String packageName = requestBasicInfo.getApplicationID();
        String appVersionName = requestBasicInfo.getAppVersionName();
        Integer appVersion = StringUtils.isEmpty(requestBasicInfo.getAppVersion()) ? 99999 : Integer.parseInt(requestBasicInfo.getAppVersion());

        //默认关闭走nacos，开启走后台管理配置
        if(getSwitchManageAdmin(getAppCode())){
            Response<List<SwitchManageDto>>  response = userSwitchManageService.getSwitchManageList(packageName, SwitchTypeEnum.PP_PV.getCode(), appVersionName, appVersion);
            if(Objects.nonNull(response) && Objects.nonNull(response.getData()) &&response.isSuccess()&& !response.getData().isEmpty()){
                return response.getData().parallelStream().anyMatch(o -> o.getStatus() == 1);
            }
            return Boolean.FALSE;
        }else{
            if (StringUtils.isEmpty(getPPVSwitch(requestBasicInfo.getAppCode()))) {
                return Boolean.FALSE;
            }

            final JSONArray ppAndPvConfigArray = JSONUtil.parseArray(getPPVSwitch(requestBasicInfo.getAppCode()));
            if (CollectionUtils.isEmpty(ppAndPvConfigArray)) {
                return Boolean.FALSE;
            }

            return ppAndPvConfigArray.stream().anyMatch(o -> {
                cn.hutool.json.JSONObject obj = (cn.hutool.json.JSONObject) o;
                if (requestBasicInfo.getAppVersionName().equals(obj.getStr("versionCode"))
                        && requestBasicInfo.getAppVersion().equals(obj.getStr("versionSerialNo"))) {
                    return obj.getInt("enableFlag").equals(switchEnable);
                }
                return Boolean.FALSE;
            });
        }
    }

    public String getAppCode() {
        return RequestLocalInfo.getRequestBasicInfo().getAppCode();
    }

    public AppEnum getApp() {
        final String appCode = RequestLocalInfo.getRequestBasicInfo().getAppCode();
        if (appCode.equals(AppCodeEnum.MEBOO.getAppCode())) {
            return AppEnum.MEBOO;
        }
        if (appCode.equals(AppCodeEnum.TOUCHU.getAppCode())) {
            return AppEnum.TOUCHU;
        }
        if (appCode.equals(AppCodeEnum.MECHAT.getAppCode())) {
            return AppEnum.MECHAT;
        }
        return AppEnum.MEBOO;
    }

    public String getAppCodeByPackageName(String packageName) {
        if (StringUtils.isEmpty(packageName)) {
            return AppCodeEnum.MEBOO.getAppCode();
        }
        return AppCodeEnum.fromPackageName(packageName).getAppCode();
    }

}
